﻿using System;
using System.Text;

namespace MatrixClass
{
    class Matrix
    {
        readonly int[,] matrix;
        readonly int rows;
        readonly int cols;

        public int Rows
        {
            get
            {
                return rows;
            }
        }

        public int Cols
        {
            get
            {
                return cols;
            }
        }

        public int this[int row, int col]
        {
            get
            {
                return matrix[row, col];
            }
            set
            {
                matrix[row, col] = value;
            }
        }

        static public Matrix operator +(Matrix a, Matrix b)
        {
            if (a.Rows != b.Rows || a.Cols != b.Cols)
            {
                throw new FormatException("Matrixes must have the same dimensions!");
            }
            Matrix result = new Matrix(a.rows, a.cols);
            for (int row = 0, rowLength = a.rows; row < rowLength; row++)
            {
                for (int col = 0, colLength = a.cols; col < colLength; col++)
                {
                    result[row, col] = a[row, col] + b[row, col];
                }
            }
            return result;
        }

        static public Matrix operator -(Matrix a, Matrix b)
        {
            if (a.rows != b.rows || a.cols != b.cols)
            {
                throw new FormatException("Matrixes must have the same dimensions!");
            }
            Matrix result = new Matrix(a.rows, a.cols);
            for (int row = 0, rowLength = a.rows; row < rowLength; row++)
            {
                for (int col = 0, colLength = a.cols; col < colLength; col++)
                {
                    result[row, col] = a[row, col] - b[row, col];
                }
            }
            return result;
        }

        public static Matrix operator *(Matrix a, Matrix b)
        {
            if (a.cols != b.rows)
            {
                throw new FormatException("First matrix columns number must be equal to second matrix rows number!");
            }
            Matrix result = new Matrix(a.Rows, a.Cols);
            for (int row = 0, rowLength = a.rows; row < rowLength; row++)
            {
                for (int col = 0, colLength = b.cols; col < colLength; col++)
                {
                    for (int aCol = 0, aColsLength = a.cols; aCol < aColsLength; aCol++)
                    {
                        result[row, col] += a[row, aCol] * b[aCol, col];
                    }
                }
            }
            return result;
        }

        public override string ToString()
        {
            StringBuilder result = new StringBuilder();
            result.Append(this[0, 0]);
            for (int cols = 1; cols < this.cols; cols++)
            {
                result.AppendFormat(" {0}", this[0, cols]);
            }
            for (int row = 1; row < this.rows; row++)
            {
                result.AppendFormat("\n{0}", this[row, 0]);
                for (int col = 1; col < this.cols; col++)
                {
                    result.AppendFormat(" {0}", this[row, col]);
                }
            }
            return result.ToString();
        }

        public Matrix(int[,] matrix)
        {
            this.matrix = (int[,])matrix.Clone();
            this.rows = matrix.GetLength(0);
            this.cols = matrix.GetLength(1);
        }

        public Matrix(Matrix matrix) : this(matrix.matrix)
        {
        }

        public Matrix(int rows, int cols) : this(new int[rows, cols])
        {
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Matrix a = new Matrix(3, 4);
            a[2, 1] = 4;
            Matrix b = new Matrix(new int[3, 4]);
            b[2, 1] = 3;
            Matrix c = new Matrix(2, 2);
            c[0, 0] = 1;
            c[0, 1] = 2;
            c[1, 1] = 3;
            c[1, 0] = 2;
            Matrix d = new Matrix(c);
            d[1, 0] = 4;

            Console.WriteLine(a + b);
            Console.WriteLine();
            Console.WriteLine(c * d);
        }
    }
}